package com.cgnpc.scp.achievement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cgnpc.cud.core.domain.AjaxResult;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.scp.achievement.mybatis.entity.*;
import com.cgnpc.scp.achievement.mybatis.mapper.client.*;
import com.cgnpc.scp.achievement.pojo.SaveStandardReq;
import com.cgnpc.scp.achievement.pojo.StandardDetail;
import com.cgnpc.scp.achievement.service.StandardService;
import com.cgnpc.scp.common.bean.CreateFileInfo;
import com.cgnpc.scp.common.bean.MyPageResult;
import com.cgnpc.scp.common.pojo.UserInfo;
import com.cgnpc.scp.common.service.ExcelCustomTemplateService;
import com.cgnpc.scp.common.utils.*;
import com.cgnpc.scp.manager.mybatis.entity.DataDict;
import com.cgnpc.scp.manager.service.IDataDictService;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class StandardServiceImpl implements StandardService
{
    private static final Logger LOGGER = LoggerFactory.getLogger(StandardServiceImpl.class);

    @Autowired
    private CurrentUser currentUser;

    @Autowired
    private IDataDictService dataDictService;

    @Autowired
    private StandardMapper standardMapper;

    @Autowired
    private StandardUserMapper standardUserMapper;

    @Autowired
    private StandardFileMapper standardFileMapper;

    @Autowired
    private SqlSession sqlSession;
    @Autowired
    private ExcelCustomTemplateService excelCustomTemplateService;

//    @Override
//    public Standard save(Standard standard) {
//        Standard re = null;
//
//        UserInfo userinfo = currentUser.getCurrentUserDetail();
//
//        try {
//            if (standard.getId() == null) {
//                standard.setId(IDHelper.uuid());
//                standard.setCreateUser(userinfo.getUserId());
//                standard.setCreateUserName(userinfo.getUserName());
//
//                standardMapper.insert(standard);
//            }else {
//                standard.setLastUpdateTime(new Date());
//                standard.setLastUpdateUser(userinfo.getUserId());
//                standard.setLastUpdateUserName(userinfo.getUserName());
//
//                standardMapper.updateById(standard);
//            }
//
//            re = standard;
//        } catch (Exception e) {
//            LOGGER.error("StandardServiceImpl save failed:", e);
//        }
//
//        return re;
//    }
    @Override
    public StandardDetail save(SaveStandardReq req) {
        //Standard re = null;
        StandardDetail re = null;
        UserInfo userinfo = currentUser.getCurrentUserDetail();

        try {
            boolean isNew = false;
            Standard standard1 = req.getStandard();
            if (standard1.getId() == null) {
                standard1.setId(IDHelper.uuid());
                standard1.setCreateUser(userinfo.getUserId());
                standard1.setCreateUserName(userinfo.getUserName());
                standardMapper.insert(standard1);
                isNew = true;
            }else {
                standard1.setLastUpdateTime(new Date());
                standard1.setLastUpdateUser(userinfo.getUserId());
                standard1.setLastUpdateUserName(userinfo.getUserName());

                standardMapper.updateById(standard1);
            }
            List<StandardUser> standardUsers = req.getStandardUsers();
            if (!isNew) {
               /* AwardUserExample example = new AwardUserExample();
                AwardUserExample.Criteria criteria = example.createCriteria();
                criteria.andAwardIdEqualTo(award.getId());
                awardUserMapper.deleteByExample(example);*/
                //QueryWrapper<StandardUser> queryWrapper = new QueryWrapper();
                QueryWrapper<StandardUser> queryWrapper = new QueryWrapper();
                queryWrapper.eq("standard_id", standard1.getId());
                standardUserMapper.delete(queryWrapper);
            }
//            if(standardUsers.size() > 0) {
//                for (StandardUser curData : standardUsers) {
//                    curData.setId(IDHelper.uuid());
//                    curData.setStandardId(curData.getId());
//                    //awardUserMapper.insertSelective(curData);
//                    standardUserMapper.insert(curData);
//                }
//            }
            List<StandardFile> standardFiles = req.getStandardFiles();
            if (!isNew) {
                /*AwardFileExample example = new AwardFileExample();
                AwardFileExample.Criteria criteria = example.createCriteria();
                criteria.andAwardIdEqualTo(award.getId());
                awardFileMapper.deleteByExample(example);*/
                QueryWrapper<StandardFile> queryWrapper = new QueryWrapper();
                queryWrapper.eq("standard_id", standard1.getId());
                standardFileMapper.delete(queryWrapper);
            }
            for (StandardFile curData : standardFiles) {
                curData.setId(IDHelper.uuid());
                curData.setStandardId(standard1.getId());
                standardFileMapper.insert(curData);
            }
            re = new StandardDetail();
            re.setStandard(standard1);
            re.setStandardUsers(standardUsers);
            re.setStandardFiles(standardFiles);
        } catch (Exception e) {
            LOGGER.error("StandardServiceImpl save failed:", e);
        }

        return re;
    }

    @Override
    public Standard getById(String id) {
        Standard re = null;

        re = standardMapper.selectById(id);

        return re;
    }

    @Override
    public MyPageResult<Standard> queryStandardPageList(Standard req) {
        MyPageResult<Standard> re = null;

        int pageNum = req.getPageNum();
        int pageSize = req.getPageSize();
        Page<Standard> queryPage = new Page<>(pageNum, pageSize);

        //StandardExample example = new StandardExample();
        QueryWrapper<Standard> queryWrapper = new QueryWrapper();
        if (req.getSubjectName() != null) {
            queryWrapper.like("subject_code", req.getSubjectCode());
            queryWrapper.like("subject_name", req.getSubjectName());
        }
        if (req.getYear() != null) {
            queryWrapper.like("year", req.getYear());
        }
        if (req.getSubjectType() != null) {
            queryWrapper.like("subject_type", req.getSubjectType());
        }
        IPage<Standard> standardPageInfo = standardMapper.selectPage(queryPage, queryWrapper);

        re = MyPageResultUtil.createMyPageResultPlus(standardPageInfo);

        return re;
    }

    @Override
    public boolean delByIds(List<String> ids) {
        boolean re = false;

        /*StandardExample example = new StandardExample();
        StandardExample.Criteria criteria = example.createCriteria();
        criteria.andIdIn(ids);*/
        standardMapper.deleteBatchIds(ids);
        re = true;

        return re;
    }
    @Override
    public <T extends Standard> CreateFileInfo exportExcel(T reqEntity) throws Exception{
        final String logInfo = "[exportExcel_UUID_" + UUID.randomUUID() + "]";
        CreateFileInfo createFileInfo = null;

        try {
            // 创建queryExample
            StandardExample standardExample = createQueryExample(reqEntity);
            // mappedStatementNamespace为mybatis生成的mapper.xml中的命名空间
            String mappedStatementNamespace = "com.cgnpc.scp.achievement.mybatis.mapper.client.StandardMapper";
            // mappedStatementMethod为mybatis生成的mapper.xml中的方法
            String mappedStatementMethod = "selectByExampleWithCustom";
            // mappedStatementId为具体指向的方法
            String mappedStatementId = mappedStatementNamespace + "." + mappedStatementMethod;

            // mappedStatementParameter可以为mybatis自动生成的XxxExample实体类，例如UserExample
            Object mappedStatementParameter = standardExample;
            //数字字典固定的值==Standard_exportExcel
            //String exportDictGroupKey = DataDictUtil.DICT_GROUP_KEY_WITH_CAPACITY_EXPORTEXCEL;
            String exportDictGroupKey = DataDictUtil.DICT_GROUP_KEY_WITH_STANDARD_EXPORTEXCEL;

            createFileInfo = excelCustomTemplateService.createXlsxToWebDir(
                    sqlSession
                    , mappedStatementId
                    , mappedStatementParameter
                    , exportDictGroupKey
            );
        } catch (Exception e) {
            LOGGER.error("{}error;", logInfo, e);
            throw e;
        }

        return createFileInfo;
    }
    /**
     * 创建查询Example
     *
     * @param reqEntity reqEntity
     * @param <T>       T
     * @return Example
     */
    private <T extends Standard> StandardExample createQueryExample(T reqEntity) {
        // mybatis查询方式
        StandardExample standardExample = new StandardExample();
        // 设置排序字段
        // queryExample.setOrderByClause("order_index");
        // 设置查询条件
        // 项目代码
        // 项目名称
        // 勾选项目----多个id
        if (ListUtil.getListSizeWith0(reqEntity.getIds()) > 0) {
            // queryExampleCriteria.andProjectNameLike(SqlUtil.valueJoinLikeBoth(reqEntity.getProjectName()));
            // addCriterion("project_name like", value, "projectName");
            standardExample.setIds(reqEntity.getIds());
        }
        return standardExample;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public <T extends Standard> AjaxResult importFromExcel(UserInfo loginUserInfo, Locale reqLocale, MultipartFile reqFile) throws Exception {
        final String logInfo = "[importFromExcel_UUID_" + UUID.randomUUID() + "]";
        AjaxResult ajaxResult = null;
        XSSFWorkbook workbook = null;
        InputStream reqFileInputStream = null;

        try {
            if (reqFile == null) {
                return AjaxResultUtil.createErrorMessage("文件不存在");
            }

            boolean reqFileEmpty = reqFile.isEmpty();
            String reqFileName = reqFile.getName();
            String reqFileOriginalFilename = reqFile.getOriginalFilename();

            LOGGER.info("{}reqFileEmpty:{};reqFileName:{};reqFileOriginalFilename:{};"
                    , logInfo
                    , reqFileEmpty, reqFileName, reqFileOriginalFilename
            );

            if (!reqFileOriginalFilename.toLowerCase().endsWith(".xlsx")) {
                LOGGER.error("{}只支持.xlsx文件。", logInfo);
                return AjaxResultUtil.createErrorMessage("只支持.xlsx文件", null);
            }

            reqFileInputStream = reqFile.getInputStream();
            workbook = new XSSFWorkbook(reqFileInputStream);
            Sheet sheet = workbook.getSheetAt(0);

            Iterator<Row> itRow = sheet.rowIterator();
            int rowIndex = 0;
            Row row = null;
            Cell cell000 = null;
            Cell cell001 = null;
            Cell cell002 = null;
            Cell cell003 = null;
            Cell cell004 = null;
            Cell cell005 = null;
            Cell cell006 = null;
            Cell cell007 = null;
            Cell cell008 = null;
            Cell cell009 = null;
            Cell cell0010 = null;
            String cellValue000 = null;
            String cellValue001 = null;
            String cellValue002 = null;
            String cellValue003 = null;
            String cellValue004 = null;
            String cellValue005 = null;
            //String cellValue006 = null;
            //String cellValue007 = null;
            Date dateCellValue6 = null;
            Date dateCellValue7 = null;
            String cellValue008 = null;
            String cellValue009 = null;
            String cellValue0010 = null;

            final List<T> reqEntityList = new ArrayList<>();
            T reqEntity = null;

            while (itRow.hasNext()) {
                row = itRow.next();

                // 第1行为标题
                if (rowIndex++ <= 0) {
                    continue;
                }

                // 课题编码
                // 课题名称
                // 课题分类
                // 立项年份
                // 专业分部
                // 课题负责人
                // 开始日期
                // 结束日期
                // 归档单位名称
                // 是否发布
                //主参编
                cell000 = row.getCell(0);
                cell001 = row.getCell(1);
                cell002 = row.getCell(2);
                cell003 = row.getCell(3);
                cell004 = row.getCell(4);
                cell005 = row.getCell(5);
                cell006 = row.getCell(6);
                cell007 = row.getCell(7);
                cell008 = row.getCell(8);
                cell009 = row.getCell(9);
                cell0010 = row.getCell(10);
                cellValue000 = ExcelUtil.getCellValue(cell000);
                cellValue001 = ExcelUtil.getCellValue(cell001);
                cellValue002 = ExcelUtil.getCellValue(cell002);
                cellValue003 = ExcelUtil.getCellValue(cell003);
                cellValue004 = ExcelUtil.getCellValue(cell004);
                cellValue005 = ExcelUtil.getCellValue(cell005);
                dateCellValue6 = cell006.getDateCellValue();
                dateCellValue7 = cell007.getDateCellValue();
                //cellValue006 = ExcelUtil.getCellValue(cell006);
                //cellValue007 = ExcelUtil.getCellValue(cell007);
                cellValue008 = ExcelUtil.getCellValue(cell008);
                cellValue009 = ExcelUtil.getCellValue(cell009);
                cellValue0010 = ExcelUtil.getCellValue(cell0010);
                reqEntity = (T) new Standard();
                reqEntityList.add(reqEntity);

                // project_code 课题编码
                reqEntity.setSubjectCode(cellValue000);
                // project_name 课题名称
                reqEntity.setSubjectName(cellValue001);
                // SubjectType 课题分类
                List<DataDict> dataDictstype = dataDictService.queryByDictGroupKey("standard_level");
                for (DataDict dataDict : dataDictstype) {
                    if (dataDict.getDictKey().equals(cellValue002)){
                        reqEntity.setSubjectType(dataDict.getDictText());
                    }
                }
                if (reqEntity.getSubjectType() == "" ) {
                    throw new RuntimeException("standard_level,Value for condition cannot be null");
                }
                //reqEntity.setSubjectType(cellValue002);
                // description 立项年份
                //NumberUtil.parseStringToIntegerWithNull(cellValue007)
                //DateUtil.parseToDate(sdfYyyymmddHhmmss, sdfYyyymmdd, cellValue009)
                reqEntity.setYear(NumberUtil.parseStringToIntegerWithNull(cellValue003));
                // dept_name 专业分部名称
                reqEntity.setDeptName(cellValue004);
                // dept_id 数字字典===专业分部
                List<DataDict> dataDicts = dataDictService.queryByDictGroupKey("achievement_profession_dept");
                for (DataDict dataDict : dataDicts) {
                    if (dataDict.getDictText().equals(cellValue004)){
                        reqEntity.setDeptId(dataDict.getId());
                    }
                }
                List<DataDict> chiefLessEditor = dataDictService.queryByDictGroupKey("chief_less_editor");
                for (DataDict dataDict : chiefLessEditor) {
                    if(dataDict.getDictText().equals(cellValue0010)){
                        reqEntity.setEditor(dataDict.getDictText());
                    }
                }
                //专业分部
                if(reqEntity.getDeptId() == "" ){
                    throw new RuntimeException("achievement_profession_dept,Value for condition cannot be null");
                }
                //主参编1或者2
                if(reqEntity.getEditor() == "" ){
                    throw new RuntimeException("chief_less_editor,Value for condition cannot be null");
                }
                // Standard_user 课题负责人
                reqEntity.setSubjectUser(cellValue005);
                // StartTime 开始日期 HSSFDateUtil
                reqEntity.setStartTime(dateCellValue6);
                // EndTime 结束日期
                reqEntity.setEndTime(dateCellValue7);
                // FinishName 归档单位名称
                reqEntity.setFinishName(cellValue008);
                // publish 是否发布
                reqEntity.setPublish(cellValue009);
                if (ListUtil.getListSizeWith0(reqEntityList) >= SqlUtil.INSERT_BATCH_MAX_ROWS) {
                    saveOrUpdate(loginUserInfo, reqLocale, reqEntityList);
                    reqEntityList.clear();
                }
            }

            if (ListUtil.getListSizeWith0(reqEntityList) > 0) {
                saveOrUpdate(loginUserInfo, reqLocale, reqEntityList);
                reqEntityList.clear();
            }
            ajaxResult = AjaxResultUtil.createSuccessMessage("保存成功");
        } catch (Exception e) {
            LOGGER.error("{}error;", logInfo, e);
            throw e;
        } finally {
            IOUtil.closeStream(reqFileInputStream);
            ExcelUtil.closeWorkbook(workbook);
        }

        return ajaxResult;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public <T extends Standard> AjaxResult saveOrUpdate(UserInfo loginUserInfo, Locale reqLocale, List<T> reqEntityList) {
        final String logInfo = "[PurchaseProject_saveOrUpdate_UUID_" + UUID.randomUUID() + "]";
        AjaxResult ajaxResult = null;

        try {
            Date nowDate = new Date();

            // begin 获取登录用户的信息
            String loginUserInfoUserId = loginUserInfo.getUserId();
            String loginUserInfoUserName = loginUserInfo.getUserName();
            // end 获取登录用户的信息

            //PurchaseProject dbPurchaseProject = null;
            Standard usedEntity = null;
            int saveRows = 0;
            int updateRows = 0;

            String reqId = null;
            String reqProjectCode = null;

            for (Standard reqEntity : reqEntityList) {
                reqId = reqEntity.getId();
                reqProjectCode = reqEntity.getSubjectCode();

                // dbPurchaseProject = purchaseProjectMapper.selectByPrimaryKey(reqId);

                if (StringUtil.isNullOrSpace(reqId)) {
                    // 保存
                    usedEntity = new Standard();
                    usedEntity.setId(IDHelper.uuidNew());
                    usedEntity.setSubjectCode(reqProjectCode);
                    usedEntity.setSubjectName(reqEntity.getSubjectName());
                    usedEntity.setSubjectType(reqEntity.getSubjectType());
                    usedEntity.setYear(reqEntity.getYear());
                    usedEntity.setDeptId(reqEntity.getDeptId());
                    usedEntity.setDeptName(reqEntity.getDeptName());
                    usedEntity.setSubjectUser(reqEntity.getSubjectUser());
                    usedEntity.setFinishName(reqEntity.getFinishName());
                    usedEntity.setPublish(reqEntity.getPublish());
                    usedEntity.setStartTime(reqEntity.getStartTime());
                    usedEntity.setEndTime(reqEntity.getEndTime());
                    usedEntity.setEditor(reqEntity.getEditor());
                    usedEntity.setCreateTime(nowDate);
                    usedEntity.setCreateUser(loginUserInfoUserId);
                    usedEntity.setCreateUserName(loginUserInfoUserName);
                    usedEntity.setLastUpdateTime(nowDate);
                    usedEntity.setLastUpdateUser(loginUserInfoUserId);
                    usedEntity.setLastUpdateUserName(loginUserInfoUserName);
                    saveRows += standardMapper.insert(usedEntity);
                } else {
                    // 修改
                    usedEntity = new Standard();
                    usedEntity.setId(reqId);
                    usedEntity.setSubjectCode(reqProjectCode);
                    usedEntity.setSubjectName(reqEntity.getSubjectName());
                    usedEntity.setSubjectType(reqEntity.getSubjectType());
                    usedEntity.setYear(reqEntity.getYear());
                    // usedEntity.setCreateTime(nowDate);
                    // usedEntity.setCreateUser(loginUserInfoUserId);
                    // usedEntity.setCreateUserName(loginUserInfoUserName);
                    usedEntity.setLastUpdateTime(nowDate);
                    usedEntity.setLastUpdateUser(loginUserInfoUserId);
                    usedEntity.setLastUpdateUserName(loginUserInfoUserName);

                    updateRows += standardMapper.updateById(usedEntity);
                }
            }

            String strResultInfo = "保存" + saveRows + "行；修改" + updateRows + "行；";

            ajaxResult = AjaxResultUtil.createSuccessMessage(strResultInfo);
        } catch (Exception e) {
            LOGGER.error("{}saveOrUpdate.error;", logInfo, e);
            throw e;
        }

        return ajaxResult;
    }

}
